package com.wechat.page.navbar;

import org.controlsfx.glyphfont.FontAwesome;
import org.springframework.beans.factory.annotation.Autowired;

import com.swak.annotation.FluxDepend;
import com.swak.fx.support.AbstractPage;
import com.swak.fx.support.Display;
import com.swak.fx.support.FXMLView;
import com.swak.fx.support.ui.UIBadge;
import com.swak.fx.support.ui.UIIcon;
import com.swak.fx.support.ui.UIImage;
import com.swak.ui.Event;
import com.swak.ui.EventListener;
import com.wechat.Cons;
import com.wechat.Cons.Menus;
import com.wechat.dto.ContactDTO;
import com.wechat.page.api.ChatApi;
import com.wechat.service.SubjectServiceAsync;

import javafx.beans.binding.Bindings;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.geometry.HPos;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.geometry.VPos;
import javafx.scene.Cursor;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.Priority;

/**
 * NavbarPage.
 * 
 * @author 618lf
 */
@FXMLView(title = "导航", value = "NavbarPage.fxml", css = "NavbarPage.css")
public class NavbarPage extends AbstractPage implements EventListener {

	final UIImage userImg;
	final UIIcon chatBtn;
	final UIIcon contactBtn;
	final UIIcon fileBtn;
	final UIIcon shareBtn;
	final UIIcon appsBtn;
	final UIIcon liveBtn;
	final UIIcon moreBtn;
	final Pane spacePane;
	final MorePopup morePopup;

	@Autowired
	private ChatApi chatApi;
	@FluxDepend
	private SubjectServiceAsync subjectService;

	public NavbarPage() {
		this.userImg = new UIImage().image(Display.logo());
		this.chatBtn = new UIIcon(FontAwesome.Glyph.COMMENT).Tip("聊天");
		this.contactBtn = new UIIcon(FontAwesome.Glyph.USER).Tip("通讯录");
		this.fileBtn = new UIIcon(FontAwesome.Glyph.FOLDER).Tip("聊天文件");
		this.shareBtn = new UIIcon(FontAwesome.Glyph.PAW).Tip("分享");
		this.appsBtn = new UIIcon(FontAwesome.Glyph.DELICIOUS).Tip("应用");
		this.liveBtn = new UIIcon(FontAwesome.Glyph.LASTFM).Tip("直播");
		this.moreBtn = new UIIcon(FontAwesome.Glyph.BARS).Tip("更多");
		this.spacePane = new Pane();
		this.morePopup = this.NewPage(MorePopup.class);
	}

	@Override
	public void initializeParts() {
		super.initializeParts();
		this.initUserImg();
		this.initIcon(chatBtn);
		this.initIcon(contactBtn);
		this.initIcon(fileBtn);
		this.initIcon(shareBtn);
		this.initIcon(liveBtn);
		this.initIcon(moreBtn);
		this.initIcon(appsBtn);

		this.addChild(userImg);
		this.addChild(chatBtn);
		this.addChild(contactBtn);
		this.addChild(fileBtn);
		this.addChild(shareBtn);
		this.addChild(spacePane);
		this.addChild(liveBtn);
		this.addChild(moreBtn);
		this.addChild(appsBtn);

		GridPane.setConstraints(userImg, 0, 0);
		GridPane.setConstraints(chatBtn, 0, 1);
		GridPane.setConstraints(contactBtn, 0, 2);
		GridPane.setConstraints(fileBtn, 0, 3);
		GridPane.setConstraints(shareBtn, 0, 4);
		GridPane.setConstraints(appsBtn, 0, 5);
		GridPane.setConstraints(spacePane, 0, 6);
		GridPane.setConstraints(liveBtn, 0, 8);
		GridPane.setConstraints(moreBtn, 0, 9);
		GridPane.setHgrow(spacePane, Priority.ALWAYS);
		GridPane.setVgrow(spacePane, Priority.ALWAYS);

		this.chatBtn.offsetXProperty().set(-15);
		this.chatBtn.offsetYProperty().set(15);
	}

	private void initUserImg() {
		userImg.setPrefWidth(38);
		userImg.setPrefHeight(38);
		GridPane.setHalignment(userImg, HPos.CENTER);
		GridPane.setValignment(userImg, VPos.CENTER);
		GridPane.setMargin(userImg, new Insets(38, 0, 10, 0));
	}

	private void initIcon(UIIcon btn) {
		btn.Size(22);
		btn.setPrefHeight(50);
		btn.setPrefWidth(55);
		btn.setAlignment(Pos.CENTER);
		btn.setCursor(Cursor.HAND);
		GridPane.setHalignment(btn, HPos.CENTER);
		GridPane.setValignment(btn, VPos.CENTER);
	}

	@Override
	public void setupEventHandlers() {
		super.setupEventHandlers();
		this.chatBtn.setOnMouseClicked(e -> {
			this.resetActiveProperty();
			this.chatActiveProperty().set(true);
		});
		this.contactBtn.setOnMouseClicked(e -> {
			this.resetActiveProperty();
			this.contactActiveProperty().set(true);
		});
		this.fileBtn.setOnMouseClicked(e -> {
			this.resetActiveProperty();
			this.fileActiveProperty().set(true);
		});
		this.shareBtn.setOnMouseClicked(e -> {
			this.resetActiveProperty();
			this.shareActiveProperty().set(true);
		});
		this.appsBtn.setOnMouseClicked(e -> {
			this.resetActiveProperty();
			this.appsActiveProperty().set(true);
		});
		this.liveBtn.setOnMouseClicked(e -> {
			this.resetActiveProperty();
			this.liveActiveProperty().set(true);
		});
		this.morePopup.bindMouseClickedWith(this.moreBtn);
	}

	private void resetActiveProperty() {
		this.chatActiveProperty().set(false);
		this.contactActiveProperty().set(false);
		this.shareActiveProperty().set(false);
		this.fileActiveProperty().set(false);
		this.appsActiveProperty().set(false);
		this.liveActiveProperty().set(false);
	}

	@Override
	public void setupBindings() {
		super.setupBindings();
//		this.userImg.nodeProperty().bind(Bindings.createObjectBinding(() -> {
//			String path = loginProperty.getHeadimgProperty().get();
//			return this.headimgStorageService.open(path);
//		}, loginProperty.getHeadimgProperty()));
		this.chatBtn.decorationProperty().bind(Bindings.createObjectBinding(() -> {
			int unread = this.chatUnreadProperty.get();
			return unread > 0 ? new UIBadge(unread) : null;
		}, this.chatUnreadProperty));
	}

	@Override
	public void setupValueChangedListeners() {
		super.setupValueChangedListeners();
		this.chatActiveProperty().addListener((ob, o, n) -> this.toggleActiveStyle(chatBtn, n));
		this.contactActiveProperty().addListener((ob, o, n) -> this.toggleActiveStyle(contactBtn, n));
		this.fileActiveProperty().addListener((ob, o, n) -> this.toggleActiveStyle(fileBtn, n));
		this.shareActiveProperty().addListener((ob, o, n) -> this.toggleActiveStyle(shareBtn, n));
		this.appsActiveProperty().addListener((ob, o, n) -> this.toggleActiveStyle(appsBtn, n));
		this.liveActiveProperty().addListener((ob, o, n) -> this.toggleActiveStyle(liveBtn, n));
	}

	private void toggleActiveStyle(UIIcon btn, boolean active) {
		if (active) {
			btn.getStyleClass().add("active");
		} else {
			btn.getStyleClass().remove("active");
		}
	}

	@Override
	public void mounted() {
		super.mounted();
		this.onMessageRecv();
	}

	@Override
	public void activated() {
		super.activated();
		this.$runContextCompleteWithUI(() -> subjectService.me()).thenAccept(c -> this.onLoadHeadimg(c));
	}

	private void onLoadHeadimg(ContactDTO contact) {
		if (contact != null && contact.getHeadimg() != null && contact.getHeadimg().getSmallHeadimgFile() != null) {
			this.userImg.nodeProperty().set(contact.getHeadimg().getSmallHeadimgFile());
		}
	}

	// ================================================================================
	// 事件监听
	// ================================================================================
	@Override
	public void listen(Event event) {
		if (LOGGER.isDebugEnabled()) {
			LOGGER.debug("[菜单栏] - 收到事件 ：{}", event);
		}

		// 切换
		if (Cons.Event_Menu_Toggle.equals(event.getKey())) {
			this.$runUI(() -> this.onMenuToggle(event.getMessage()));
		} else if (Cons.Event_Msg_Recv.equals(event.getKey())) {
			this.$runUI(() -> this.onMessageRecv());
		}
	}

	private void onMessageRecv() {
		this.$run(() -> {
			this.chatApi.unreads().thenAccept(c -> {
				this.$runUI(() -> this.chatUnreadProperty.set(c == null || c < 0 ? 0 : c));
			});
		});
	}

	private void onMenuToggle(Menus menu) {
		this.resetActiveProperty();
		if (menu == null || menu == Menus.Chat) {
			this.chatActiveProperty().set(true);
		}
	}

	// ================================================================================
	// Properties
	// ================================================================================
	private IntegerProperty chatUnreadProperty = new SimpleIntegerProperty(0);
	private BooleanProperty chatActiveProperty = new SimpleBooleanProperty(false);
	private BooleanProperty contactActiveProperty = new SimpleBooleanProperty(false);
	private BooleanProperty fileActiveProperty = new SimpleBooleanProperty(false);
	private BooleanProperty shareActiveProperty = new SimpleBooleanProperty(false);
	private BooleanProperty appsActiveProperty = new SimpleBooleanProperty(false);
	private BooleanProperty liveActiveProperty = new SimpleBooleanProperty(false);

	public BooleanProperty chatActiveProperty() {
		return chatActiveProperty;
	}

	public BooleanProperty contactActiveProperty() {
		return contactActiveProperty;
	}

	public BooleanProperty fileActiveProperty() {
		return fileActiveProperty;
	}

	public BooleanProperty shareActiveProperty() {
		return shareActiveProperty;
	}

	public BooleanProperty appsActiveProperty() {
		return appsActiveProperty;
	}

	public BooleanProperty liveActiveProperty() {
		return liveActiveProperty;
	}
}